/*
 * Copyright (c) 2020, yifengling0. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. No personal names or organizations' names associated with the
 *    Atomthreads project may be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#include "atom.h"
#include <stdio.h>
#include "atomtimer.h"
#include "atomport-private.h"
#include "board.h"
#include "event.h"
#include "debug.h"
#include "console.h"
#include <string.h>
#include "iosdrv.h"
#include "eventmgr.h"
#include "syslog.h"
#include "appcmd.h"
/* Constants */



/* Local data */

/* Application threads' TCBs */
static ATOM_TCB main_tcb = DEFAULT_TCB("main");

/* Main thread's stack area */
static uint8_t main_thread_stack[ATOM_MAIN_STACK_SIZE_BYTES];

/* Idle thread's stack area */
static uint8_t idle_thread_stack[ATOM_IDLE_STACK_SIZE_BYTES];

/* Forward declarations */
static void main_thread_func (uint32_t data);

/**
 * \b main
 *
 * Program entry point.
 *
 * Creates an application thread and starts the OS.
 */

void main ( void )
{
    int8_t status;

#ifdef COM_USE_CONSOLE
    ConsoleInit();
    AppCmdInit();
#endif    

    IosDrvInit();
    board_init();
    DebugPortSetDevice(BSP_DBGPORT_DEVICE_NAME);
    /**
     * Note: to protect OS structures and data during initialisation,
     * interrupts must remain disabled until the first thread
     * has been restored. They are reenabled at the very end of
     * the first thread restore, at which point it is safe for a
     * reschedule to take place.
     */

    /**
     * Initialise the OS before creating our threads.
     */
    archInitSystemTickTimer();
             
    status = atomOSInit(&idle_thread_stack[0], ATOM_IDLE_STACK_SIZE_BYTES, TRUE);
    
     if (status == ATOM_OK)
     {
          /* Create an application thread */ 
          status = atomThreadCreate(&main_tcb,
                       16, main_thread_func, 0,
                       &main_thread_stack[0],
                       ATOM_MAIN_STACK_SIZE_BYTES,
                       TRUE);
 
         if (status == ATOM_OK)
          {
            /**
              * First application thread successfully created. It is
              * now possible to start the OS. Execution will not return
              * from atomOSStart(), which will restore the context of
              * our application thread and start executing it.
              *
              * Note that interrupts are still disabled at this point.
              * They will be enabled as we restore and execute our first
              * thread in archFirstThreadRestore().
              */
              atomOSStart();
          }
     }

    while (1)
        ;

    /* There was an error starting the OS if we reach here */
    //return (0);
}

// #define TIMEOUT_TICK (20)

// static ATOM_TIMER timer_cb;
// static void atomMutexTimerCallback (POINTER cb_data);

// static void TickTimerRegister(int timeout)
// {
//     timer_cb.cb_func = atomMutexTimerCallback;
//     timer_cb.cb_data = &timer_cb;
//     timer_cb.cb_ticks = timeout;
//     atomTimerRegister (&timer_cb);
// }

// static void atomMutexTimerCallback (POINTER cb_data)
// {
//     event_mgr_set(EVENT_TIMER, TIMEOUT_TICK);
//     TickTimerRegister(TIMEOUT_TICK);
// }
#if defined(COM_USE_DBGPORT) && defined(APP_USE_LOG)
static const char logo[] = {
"\r\n\
--------------------------------------------- \r\n\
 __   __  _______  _______  ___      _______  \r\n\
|  |_|  ||   _   ||       ||   |    |       | \r\n\
|       ||  |_|  ||    _  ||   |    |    ___| \r\n\
|       ||       ||   |_| ||   |    |   |___  \r\n\
|       ||       ||    ___||   |___ |    ___| \r\n\
| ||_|| ||   _   ||   |    |       ||   |___  \r\n\
|_|   |_||__| |__||___|    |_______||_______| \r\n\
                                              \r\n\
                    powered   by yifengling0  \r\n\
                    ver "APP_VERSION" "__DATE__"      \r\n\
                      QQ Qun: 43141468 ←      \r\n\
--------------------------------------------- \r\n\
"
};
#endif
/**
 * \b main_thread_func
 *
 * Entry point for main application thread.
 *
 * This is the first thread that will be executed when the OS is started.
 *
 * @param[in] data Unused (optional thread entry parameter)
 *
 * @return None
 */
static void main_thread_func (uint32_t data)
{
#ifdef APP_USE_LOG  
    KPrint(logo);
#endif    
    
#ifdef COM_USE_CONSOLE    
    ConsoleRun();
#endif    
    //TickTimerRegister(TIMEOUT_TICK);
    
    SYSLOG(LOG_INFO, "System init success!");
   
    while(1){
        // ATOM_EX_EVENT event;
        // //watchdog_feed();
        // event_mgr_wait(&event, 0);
        // //处理调试命令
        
        // if( event.type == EVENT_TIMER){ //超时处理
 
        // }else{
        //     KPrint("system failure\r\n");
        // }
        atomTimerDelay(100);
    }

}